package com.ruoyi.user.service.ip;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CountryResponse;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: houyong
 * @date: 2025年11月14日 15:43
 */
@Component
@ConfigurationProperties(prefix = "ip.language")
public class IpLanguageMatcher {
    // 国家代码 -> 目标语言映射表（ISO 639-1 语言代码）
    // 支持：英语(en)、法语(fr)、阿拉伯语(ar)、西班牙语(es)、印尼语(id)、泰语(th)
    private static final Map<String, String> COUNTRY_LANGUAGE_MAP = new HashMap<>();

    static {
        // 法语国家/地区
        COUNTRY_LANGUAGE_MAP.put("FR", "fr"); // 法国
        COUNTRY_LANGUAGE_MAP.put("BE", "fr"); // 比利时（法语区）
        COUNTRY_LANGUAGE_MAP.put("CH", "fr"); // 瑞士（法语区）
        COUNTRY_LANGUAGE_MAP.put("CA", "fr"); // 加拿大（法语区）
        COUNTRY_LANGUAGE_MAP.put("MC", "fr"); // 摩纳哥

        // 阿拉伯语国家/地区
        COUNTRY_LANGUAGE_MAP.put("AE", "ar"); // 阿联酋
        COUNTRY_LANGUAGE_MAP.put("SA", "ar"); // 沙特阿拉伯
        COUNTRY_LANGUAGE_MAP.put("EG", "ar"); // 埃及
        COUNTRY_LANGUAGE_MAP.put("IQ", "ar"); // 伊拉克
        COUNTRY_LANGUAGE_MAP.put("LY", "ar"); // 利比亚
        COUNTRY_LANGUAGE_MAP.put("MA", "ar"); // 摩洛哥
        COUNTRY_LANGUAGE_MAP.put("DZ", "ar"); // 阿尔及利亚

        // 西班牙语国家/地区
        COUNTRY_LANGUAGE_MAP.put("ES", "es"); // 西班牙
        COUNTRY_LANGUAGE_MAP.put("MX", "es"); // 墨西哥
        COUNTRY_LANGUAGE_MAP.put("AR", "es"); // 阿根廷
        COUNTRY_LANGUAGE_MAP.put("CO", "es"); // 哥伦比亚
        COUNTRY_LANGUAGE_MAP.put("CL", "es"); // 智利
        COUNTRY_LANGUAGE_MAP.put("PE", "es"); // 秘鲁
        COUNTRY_LANGUAGE_MAP.put("CU", "es"); // 古巴

        // 印尼语国家
        COUNTRY_LANGUAGE_MAP.put("ID", "id"); // 印度尼西亚

        // 泰语国家
        COUNTRY_LANGUAGE_MAP.put("TH", "th"); // 泰国

        // 英语国家/地区（默认覆盖，但优先显式定义）
        COUNTRY_LANGUAGE_MAP.put("US", "en"); // 美国
        COUNTRY_LANGUAGE_MAP.put("GB", "en"); // 英国
        COUNTRY_LANGUAGE_MAP.put("AU", "en"); // 澳大利亚
        COUNTRY_LANGUAGE_MAP.put("CA", "en"); // 加拿大（英语区，注：加拿大双语，此处按IP归属细分）
        COUNTRY_LANGUAGE_MAP.put("NZ", "en"); // 新西兰

        COUNTRY_LANGUAGE_MAP.put("CN", "中文");
    }

    // 注入国家-语言映射配置
    private Map<String, String> mapping;
    private DatabaseReader databaseReader;

    // getter和setter方法
    public Map<String, String> getMapping() {
        return mapping;
    }

    public void setMapping(Map<String, String> mapping) {
        this.mapping = mapping;
    }

    // 初始化 IP 库读取器（项目启动时加载）
    @PostConstruct
    public void init() throws Exception {
        // 使用Spring原生工具读取classpath下的文件
        ClassPathResource resource = new ClassPathResource("ipdb/GeoLite2-Country.mmdb");
        // 获取文件流（注意：ResourceUtil.getFile() 本质也是读取流，MaxMind支持直接用流初始化）
        try (InputStream inputStream = resource.getInputStream()) {
            databaseReader = new DatabaseReader.Builder(inputStream).build();
        }
    }

    /**
     * 根据 IP 地址获取目标语言（ISO 639-1 代码）
     *
     * @param ipAddress IP地址（如 "8.8.8.8"、"203.151.136.1"）
     * @return 语言代码（如 "en"、"fr"、"ar" 等），默认返回 "en"
     */
    public String getLanguageByIp(String ipAddress) {
        // 1. 过滤本地/无效IP，直接返回默认英语
        if (isLocalOrInvalidIp(ipAddress)) {
            return "en";
        }
        try {
            // 2. 解析IP对应的国家代码
            InetAddress inetAddress = InetAddress.getByName(ipAddress);
            CountryResponse response = databaseReader.country(inetAddress);
            String countryCode = response.getCountry().getIsoCode();
            // 3. 根据国家代码映射语言，无匹配则返回默认英语
            return COUNTRY_LANGUAGE_MAP.getOrDefault(countryCode, "en");
        } catch (Exception e) {
            // 解析失败（如IP不在数据库、网络异常等），返回默认英语
            return "en";
        }
    }


    /**
     * 判断是否为本地IP或无效IP
     *
     * @param ipAddress IP地址
     * @return true=本地/无效IP
     */
    private boolean isLocalOrInvalidIp(String ipAddress) {
        try {
            InetAddress inetAddress = InetAddress.getByName(ipAddress);
            // 本地回环地址（127.0.0.1、::1）或私有IP（192.168.x.x等）
            return inetAddress.isLoopbackAddress() || inetAddress.isSiteLocalAddress();
        } catch (Exception e) {
            // 无效IP格式
            return true;
        }
    }


    // 判断是否为本地 IP（包括回环地址和私有 IP）
    private boolean isLocalIp(String ipStr) {
        try {
            InetAddress inetAddress = InetAddress.getByName(ipStr);
            // 本地回环地址（127.0.0.1 或 ::1）
            if (inetAddress.isLoopbackAddress()) {
                return true;
            }
            // 私有 IP 地址（如 192.168.x.x、10.x.x.x 等，可选判断）
            return inetAddress.isSiteLocalAddress();
        } catch (UnknownHostException e) {
            return false; // 无效 IP 也视为“非本地”，后续会在解析时报错
        }
    }
}
